home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
gfx
/
conv
/
unmovie.lha
/
unmovie
/
unmovie.c
< prev
Wrap
C/C++ Source or Header
|
1992-06-07
|
9KB
|
409 lines
#include <stdio.h>
#include <iff/ilbm.h>
#define ID_DLTA MakeID('D','L','T','A')
#define ID_ANSQ MakeID('A','N','S','Q')
#define ID_FORM MakeID('F','O','R','M')
char even[120000];
char odd[120000];
char packed[120000];
struct {long name;
long len; } chunk;
long next_form_pos = 0x0C;
long next_chunk_pos = 0x34;
BitMapHeader ilbmbmhd;
char cmap[32*sizeofColorRegister];
int cmap_len;
char camg[4];
int camg_len;
FILE *in, *out;
int frame = 1;
struct {
short uni_flag;
short y_size;
short num_blocks; } wall;
struct {
short uni_flag;
short y_size;
short x_size;
short num_blocks; } pile;
long raster_size, plane_size, image_size, insize;
void
next_form()
{
int q;
q=fseek(in, next_form_pos, SEEK_SET);
if (q!=0) {
printf("FSEEK fails in 'next_form': dest was %ld\n", next_chunk_pos);
exit(0);
}
fread(&chunk, (size_t)sizeof(chunk), (size_t)1, in);
next_form_pos = ftell(in) + chunk.len;
next_chunk_pos = ftell(in)+0x04;
}
void
next_chunk()
{
int q;
q=fseek(in, next_chunk_pos, SEEK_SET);
if (q!=0) {
printf("FSEEK fails in 'next_chunk': dest was %ld\n", next_chunk_pos);
exit(0);
}
fread(&chunk, (size_t)sizeof(chunk), (size_t)1, in);
next_chunk_pos = ftell(in) + chunk.len;
}
delta_proc(buffer)
char *buffer;
{
short change_type;
long seek_val;
int b;
short offset;
long x, y, z;
char charval;
long real_offset;
char *dest;
while(!feof(in)) {
fread(&change_type, (size_t)sizeof(short), (size_t)1, in);
switch(change_type) {
case 0: /* End of DELTA */
return;
case 1: /* Wall */
fread(&wall, (size_t)sizeof(wall), (size_t)1, in);
for (b=0; b<wall.num_blocks; b++) {
fread(&offset, (size_t)2, (size_t)1, in);
real_offset = ((long)offset/raster_size) * ilbmbmhd.nPlanes;
real_offset *= raster_size;
real_offset += offset % raster_size;
for (z=0; z<ilbmbmhd.nPlanes; z++) {
for (y=0; y<wall.y_size; y++) {
fread(&charval, (size_t)1, (size_t)1, in);
dest = buffer;
dest += z * raster_size*wall.y_size;
dest += y * raster_size;
dest += real_offset;
if (wall.uni_flag == 1)
*dest ^= charval;
else
*dest = charval;
}
}
/*
* If we've stopped on an odd boundary, read and throw away
* another byte.
*/
seek_val = ftell(in);
if (seek_val & 0x01L)
fread(&charval, (size_t)1, (size_t)1, in);
}
break;
case 2: /* Pile */
fread(&pile, (size_t)sizeof(pile), (size_t)1, in);
for (b=0; b<pile.num_blocks; b++) {
fread(&offset, (size_t)2, (size_t)1, in);
real_offset = ((long)offset/raster_size) * ilbmbmhd.nPlanes;
real_offset *= raster_size;
real_offset += offset % raster_size;
for (z=0; z<ilbmbmhd.nPlanes; z++) {
for (y=0; y<pile.y_size; y++) {
for (x=0; x<pile.x_size; x++) {
fread(&charval, (size_t)1, (size_t)1, in);
dest = buffer;
dest += z * raster_size*pile.y_size;
dest += y * raster_size;
dest += real_offset + x;
if (pile.uni_flag == 1)
*dest ^= charval;
else
*dest = charval;
}
}
}
/*
* If we've stopped on an odd boundary, read and throw away
* another byte.
*/
seek_val = ftell(in);
if (seek_val & 0x01L)
fread(&charval, (size_t)1, (size_t)1, in);
}
break;
default:
printf("I seem to have found change_type %d\n", change_type);
printf("I didn't think there was such a thing!\n");
exit(1);
break;
}
}
}
/*----------------------------------------------------------------------*
* unpacker.c Convert data from "cmpByteRun1" run compression. 11/15/85
*
* By Jerry Morrison and Steve Shaw, Electronic Arts.
* This software is in the public domain.
*
* control bytes:
* [0..127] : followed by n+1 bytes of data.
* [-1..-127] : followed by byte to be repeated (-n)+1 times.
* -128 : NOOP.
*
* This version for the Commodore-Amiga computer.
* Manxified and simplified slightly by SDB...
*----------------------------------------------------------------------*/
/* This macro computes the worst case packed size of a "row" of bytes. */
#define MaxPackedSize(rowSize) ( (rowSize) + ( ((rowSize)+127) >> 7 ) )
/*----------- UnPackRow ------------------------------------------------*/
#define UGetByte() (*source++)
#define UPutByte(c) (*dest++ = (c))
/* Given POINTERS to POINTER variables, unpacks one row, updating the source
* and destination pointers until it produces dstBytes bytes. */
int UnPackRow(BYTE **pSource, BYTE **pDest, int srcBytes0, int dstBytes0)
/* BYTE **pSource, **pDest; int srcBytes0, dstBytes0; */
{
register BYTE *source = *pSource;
register BYTE *dest = *pDest;
register int n;
register BYTE c;
register int srcBytes = srcBytes0, dstBytes = dstBytes0;
int error = TRUE; /* assume error until we make it through the loop */
WORD minus128 = -128; /* get the compiler to generate a CMP.W */
while( dstBytes > 0 ) {
if ( (srcBytes -= 1) < 0 ) goto ErrorExit;
n = UGetByte();
if (n >= 0) {
n += 1;
if ( (srcBytes -= n) < 0 ) goto ErrorExit;
if ( (dstBytes -= n) < 0 ) goto ErrorExit;
do { UPutByte(UGetByte()); } while (--n > 0);
}
else if (n != minus128) {
n = -n + 1;
if ( (srcBytes -= 1) < 0 ) goto ErrorExit;
if ( (dstBytes -= n) < 0 ) goto ErrorExit;
c = UGetByte();
do { UPutByte(c); } while (--n > 0);
}
}
error = FALSE; /* success! */
ErrorExit:
*pSource = source; *pDest = dest;
return(error);
}
save_block(filename, block)
char *filename, *block;
{
FILE *out;
out = fopen(filename, "w");
chunk.name = ID_FORM;
chunk.len = image_size + sizeof(ilbmbmhd) + cmap_len + 28;
if (camg_len)
chunk.len += camg_len+8;
fwrite(&chunk, (size_t)sizeof(chunk), (size_t)1, out);
chunk.name = ID_ILBM;
fwrite(&chunk, (size_t)sizeof(chunk.name), (size_t)1, out);
chunk.name = ID_BMHD;
chunk.len = sizeof(ilbmbmhd);
fwrite(&chunk, (size_t)sizeof(chunk), (size_t)1, out);
fwrite(&ilbmbmhd, (size_t)sizeof(ilbmbmhd), (size_t)1, out);
chunk.name = ID_CMAP;
chunk.len = cmap_len;
fwrite(&chunk, (size_t)sizeof(chunk), (size_t)1, out);
fwrite(&cmap, (size_t)cmap_len, (size_t)1, out);
if (camg_len) {
chunk.name = ID_CAMG;
chunk.len = camg_len;
fwrite(&chunk, (size_t)sizeof(chunk), (size_t)1, out);
fwrite(&camg, (size_t)camg_len, (size_t)1, out);
}
chunk.name = ID_BODY;
chunk.len = image_size;
fwrite(&chunk, (size_t)sizeof(chunk), (size_t)1, out);
fwrite(block, (size_t)image_size, (size_t)1, out);
fclose(out);
}
/***************************************************************/
main(argc, argv)
int argc;
char *argv[];
{
int oddframe;
int read_size;
char *inptr, *outptr;
long i, j;
char filename[20];
if (argc != 2) {
printf("Usage: unmovie file.movie\n");
printf("Generates files named f??? representing successive frames\n");
printf("of the movie, in the same directory.\n");
printf("For looping movies, the last two frames will be the same as\n");
printf("the first two.\n");
printf("For ping-pong movies, the last frame will equal the third\n");
printf("from last frame.\n");
exit(0);
}
in = fopen(argv[1], "r");
if (in == NULL) {
printf("Can't seem to open %s for input!\n", argv[1]);
exit(1);
}
/*
* First read in the BMHD
*/
fseek(in, 0x20, SEEK_SET);
fread(&ilbmbmhd, (size_t)sizeof(ilbmbmhd), (size_t)1, in);
raster_size = (ilbmbmhd.w+7)/8;
plane_size = raster_size * ilbmbmhd.h;
image_size = plane_size * ilbmbmhd.nPlanes;
/*
* Scan for the BODY. If we encounter a CAMG or a CMAP, store it
* for later.
*/
cmap_len = 0;
camg_len = 0;
for (;;) {
next_chunk();
if (chunk.name == ID_BODY)
break;
else if (chunk.name == ID_CMAP) {
cmap_len = chunk.len;
fread(&cmap, (size_t)cmap_len, (size_t)1, in);
}
else if (chunk.name == ID_CAMG) {
camg_len = chunk.len;
fread(&camg, (size_t)camg_len, (size_t)1, in);
}
}
/*
* Read it in.
*/
read_size = fread(packed, (size_t)chunk.len, (size_t)1, in);
if (read_size != 1) {
printf("Couldn't read the first image - corrupt file?\n");
exit(1);
}
inptr = packed;
outptr = even;
for (outptr = even; outptr<&even[image_size]; ) {
insize = &packed[chunk.len] - inptr;
if (ilbmbmhd.compression == cmpByteRun1) {
if (UnPackRow(&inptr, &outptr, (int)insize,
(int)raster_size)) {
printf("Some sort of unpacker error!\n");
exit(1);
}
} else {
/*
* Uncompressed input - just copy it
*/
memcpy(outptr, inptr, raster_size);
outptr += raster_size;
inptr += raster_size;
}
}
/*
* Store the body out as f001
*/
printf("Storing frame f001\n");
ilbmbmhd.compression = cmpNone;
save_block("f001", even);
/*
* Copy to the "odd" buffer
*/
memcpy(odd, even, sizeof(even));
next_form();
for (oddframe=FALSE;;oddframe=!oddframe) {
/*
* We're through if the next chunk is ANSQ
*/
next_chunk();
if (chunk.name == ID_ANSQ)
break;
/*
* Find the next DLTA
*/
next_form();
while (chunk.name != ID_DLTA) {
next_chunk();
}
delta_proc(oddframe ? odd : even);
frame += 1;
sprintf(filename, "f%03d", frame);
printf("Storing frame %s\n", filename);
save_block(filename, oddframe ? odd : even);
}
exit(0);
}